import 'package:flutter/material.dart';
import 'package:xws/helpers/safe_value_notifier.dart';
import 'package:xws/res/images.dart';
import 'package:xws/ui/root/app_root.dart';
import 'package:xws/utils/app_util.dart';
import 'package:xws/utils/theme_util.dart';
import 'package:xws/utils/tools_util.dart';
import 'package:xws/widgets/app_btn.dart';
import 'package:xws/widgets/ex_value_builder.dart';

import 'guide_item.dart';

/// 引导对象
class _GuideObj {
  _GuideObj(this.text, this.image);

  final String text;
  final String image;
}

/// 引导状态
class _GuideState {
  _GuideState(this.overDetail, this.page);

  _GuideState.init() {
    overDetail = 0;
    page = 0;
  }

  late double overDetail;
  late int page;

  _GuideState copyWith({
    double? overDetail,
    int? page,
  }) =>
      _GuideState(overDetail ?? this.overDetail, page ?? this.page);
}

/// 引导页
class GuidPage extends StatefulWidget {
  const GuidPage({Key? key}) : super(key: key);

  @override
  State<GuidPage> createState() => _GuidPageState();
}

class _GuidPageState extends State<GuidPage> {
  late SafeValueNotifier<_GuideState> _guidState;

  final List<_GuideObj> _data = <_GuideObj>[
    _GuideObj('附近旧物', R.sp0),
    _GuideObj('只送不卖', R.sp1),
    _GuideObj('好物共享', R.sp2),
  ];

  bool _isOver = false;

  @override
  void initState() {
    super.initState();
    _guidState = SafeValueNotifier<_GuideState>(_GuideState.init());
  }

  @override
  void dispose() {
    _guidState.dispose();
    super.dispose();
  }

  Future<void> _enter() async {
    push(context, const AppRoot(), remove: true, routeType: RouteType.fade);
  }

  /// 滚动监听
  bool _onNotification(ScrollUpdateNotification s) {
    final double over = s.metrics.maxScrollExtent - s.metrics.pixels;

    if (over <= 0) {
      _guidState.value = _guidState.value.copyWith(overDetail: -over * 0.8);
    }

    if (s.dragDetails == null && (-over >= 60) && !_isOver) {
      _isOver = true;
      delayed(const Duration(milliseconds: 350)).then((_) {
        _enter();
      });
    }

    return false;
  }

  /// 根据偏移量计算透明度
  double _handleOpcity(double offset) {
    final double o = offset / 60;

    if (o < 0) return 0;
    if (o > 1) return 1;

    return o;
  }

  @override
  Widget build(BuildContext context) {
    return ColoredBox(
      color: white(context),
      child: Stack(
        children: <Widget>[
          NotificationListener<ScrollUpdateNotification>(
            onNotification: _onNotification,
            child: PageView.builder(
              physics: const BouncingScrollPhysics(),
              itemCount: _data.length,
              itemBuilder: (_, int i) => _buildItem(_data[i]),
              onPageChanged: (int p) {
                _guidState.value = _guidState.value.copyWith(page: p);
              },
            ),
          ),
          _buildWave,
          _buildIndicator,
          _buildSkipBtn,
        ],
      ),
    );
  }

  /// 构建跳过按钮
  Widget get _buildSkipBtn {
    return Align(
      alignment: Alignment.topRight,
      child: Padding(
        padding: const EdgeInsets.all(40.0).copyWith(right: 20),
        child: AppBtn(
          onTap: _enter,
          text: '跳过',
          textStyle: TextStyle(
            color: theme(context),
            fontWeight: FontWeight.bold,
          ),
          padding: const EdgeInsets.all(10),
          color: Colors.transparent,
        ),
      ),
    );
  }

  /// 构建指示器
  Widget get _buildIndicator {
    return Positioned(
      bottom: 50,
      left: 0,
      right: 0,
      child: ExValueBuilder<_GuideState>(
        valueListenable: _guidState,
        shouldRebuild: (_GuideState p, _GuideState n) => p.page != n.page,
        builder: (_, _GuideState g, __) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: List<Widget>.generate(
              _data.length,
              (int i) {
                return AnimatedContainer(
                  width: g.page == i ? 20 : 10,
                  height: 10,
                  duration: const Duration(milliseconds: 200),
                  margin: const EdgeInsets.symmetric(horizontal: 4),
                  decoration: BoxDecoration(
                    color: theme(context).withOpacity(g.page == i ? 1 : 0.5),
                    borderRadius: BorderRadius.circular(5),
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }

  /// 构建波浪
  Widget get _buildWave {
    return Positioned(
      bottom: 0,
      top: 0,
      right: 0,
      child: ClipPath(
        clipper: const _WaveClipper(),
        child: ExValueBuilder<_GuideState>(
          valueListenable: _guidState,
          shouldRebuild: (_GuideState p, _GuideState n) => p.overDetail != n.overDetail,
          builder: (_, _GuideState g, __) {
            return Container(
              width: g.overDetail,
              child: Icon(
                Icons.arrow_forward_ios_rounded,
                size: 18,
                color: white(context),
              ),
              alignment: Alignment.center,
              color: theme(context).withOpacity(_handleOpcity(g.overDetail)),
            );
          },
        ),
      ),
    );
  }

  /// 项
  Widget _buildItem(_GuideObj g) => GuideItem(
        text: g.text,
        image: g.image,
      );
}

class _WaveClipper extends CustomClipper<Path> {
  const _WaveClipper();

  @override
  Path getClip(Size size) {
    final double w = size.width;
    final double h = size.height;

    return Path()
      ..moveTo(w, 0)
      ..lineTo(w, h)
      ..quadraticBezierTo(-w, h / 2, w, 0);
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
